import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import * as dayjs from 'dayjs'
import { Observable } from 'rxjs'
import { NzMessageService } from 'ng-zorro-antd'
import { STColumn } from '@delon/abc'
import { SettingsService } from '@delon/theme'

import { I18NService } from '@core'
import { ListBaseClass } from '@shared/classes/ListBaseClass'
import { ITradeStatistic, ITradeStatisticQueryParams, ITradeStatisticPagination } from '@shared/interfaces/trade'
import { ISearchSchema, ISearchOption } from '@shared/interfaces/search'
import { ESearchType, ETradeChannel, EPaymentBrand } from '@shared/enums'
import { TradeService } from '../trade-abstract.service'
import { today } from 'app/utils/contraints'
import { EDateLimitEnum, Currency } from '@shared/interfaces/common'
import { openDownloadDialog, numScale } from 'app/utils/helpers'
import { CurrencyService } from '@shared/services/currency.service'
import { AAMSFilterInit } from '@shared/interfaces/aams'
import { LevelService } from '@shared/services/level.service'
import { ChannelService } from '@shared/services/channel.service'
import { take } from 'rxjs/operators'

enum LevelEnum {
  Institution = 'institution',
  Agent = 'agent',
  Merchant = 'merchant',
  Store = 'store',
}

const defaultCurrency: Currency = {
  code: 'AED',
  decimal: 2,
  name: 'United Arab Emirates dirham',
  number: '784',
  sign: 'د.إ',
  _id: '597aa5800b653e04bc6615ea',
}

@Component({
  selector: 'app-trades-statistics',
  templateUrl: './statistics.component.html',
  styleUrls: ['../../../shared/styles/table.less'],
})
export class TradesStatisticsComponent extends ListBaseClass<ITradeStatistic, ITradeStatisticQueryParams>
  implements OnInit, AAMSFilterInit {
  math = Math
  numScale = numScale

  channelOptions$: Observable<ISearchOption[]>
  channelOptions: ISearchOption[] = Object.keys(ETradeChannel).map(key => ({
    label: this.trans(ETradeChannel[key]),
    value: key,
  }))

  @ViewChild('tplChannel') tplChannel: TemplateRef<void>
  @ViewChild('tplCurrency') tplCurrency: TemplateRef<void>
  @ViewChild('tplLevel') tplLevel: TemplateRef<void>
  @ViewChild('tplAcquirer') tplAcquirer: TemplateRef<void>
  @ViewChild('tplGroup') tplGroup: TemplateRef<void>
  @ViewChild('tplMerchant') tplMerchant: TemplateRef<void>
  @ViewChild('tplStore') tplStore: TemplateRef<void>
  levelOptions: ISearchOption[] = []

  totalData: ITradeStatistic // 总计的数据
  selectedCurrency: Currency = defaultCurrency
  selectedLevel: LevelEnum = LevelEnum.Store
  selectedChannel: EPaymentBrand

  searchSchema: ISearchSchema[] = []
  customSchema: ISearchSchema[] = []

  insCode: string // 关联层级的机构号

  columns: STColumn[] = []
  constructor(
    public msg: NzMessageService,
    public i18n: I18NService,
    public route: ActivatedRoute,
    public router: Router,
    public settingService: SettingsService,
    private tradeService: TradeService,
    private currencyService: CurrencyService,
    private levelService: LevelService,
    private channelService: ChannelService,
  ) {
    super(msg, i18n, route, router, settingService)
  }

  ngOnInit() {
    this.initLevelOptions()
    this.initChannelOptions()
    this.initAndUpdateColumns()
    this.getInsCode()
    this.getFirstCurrency() // TODO:该方法的调用还需优化
    this.initSearchParams()
    this.handleSearch()
    this.initialAAMSFilter()
  }

  initLevelOptions(): void {
    const { userType } = this.settingService.user
    this.levelOptions = this.levelService.getLevelOptions(userType)
  }

  initChannelOptions(): void {
    this.channelOptions$ = this.channelService.getCurrentSupportChannelOptions()
  }

  initialAAMSFilter() {
    this.initAcquirer()
    this.initAgent()
    this.initMerchant()
    this.initStore()
  }

  getDecimalByCurrencyCode(currCode: string): Observable<number> {
    return this.currencyService.getDecimalByCode(currCode)
  }

  getInsCode(): void {
    this.insCode = this.settingService.user.insCode
  }
  // 获取到机构的第一个币种
  getFirstCurrency(): void {
    this.currencyService
      .getList(this.insCode)
      .pipe(take(1))
      .subscribe(res => {
        Object.assign(this.selectedCurrency, res[0])
        this.handleSearch()
      })
  }

  handleLevelChange(level): void {
    this.selectedLevel = level
    this.initAndUpdateColumns()
  }

  initAndUpdateColumns() {
    this.columns = [
      {
        title: this.getCodeTitle(),
        index: 'code',
        width: '150px',
        className: 'text-center',
      },
      {
        title: this.getNameTitle(),
        index: 'name',
        width: '150px',
        className: 'text-center',
      },
      {
        title: '收款笔数',
        i18n: 'TRADE.STATS.CHARGE.COUNT',
        index: 'positiveTransNum',
        width: '100px',
        className: 'text-center',
      },
      {
        title: '收款金额',
        i18n: 'TRADE.STATS.CHARGE.AMT',
        width: '100px',
        className: 'text-center',
        render: 'positiveTransAmt',
      },
      {
        title: '退款笔数',
        i18n: 'TRADE.STATS.REFUND.COUNT',
        index: 'negativeTransNum',
        width: '100px',
        className: 'text-center',
      },
      {
        title: '退款金额',
        i18n: 'TRADE.STATS.REFUND.AMT',
        width: '100px',
        className: 'text-center',
        render: 'negativeTransAmt',
      },
      {
        title: '总计笔数',
        i18n: 'TRADE.STATS.TOTAL.COUNT',
        index: 'totalTransNum',
        width: '100px',
        className: 'text-center',
      },
      {
        title: '总计金额',
        i18n: 'TRADE.STATS.TOTAL.AMT',
        width: '100px',
        className: 'text-center',
        render: 'totalTransAmt'
      },
    ]
  }

  initSearchParams(): void {
    this.searchSchema = [
      {
        label: 'TRADE.TRANS_TIME',
        labelI18n: 'TRADE.TRANS_TIME',
        index: ['paidAtFrom', 'paidAtTo'],
        type: ESearchType.dateRange,
        allowClear: false,
        dateLimitType: EDateLimitEnum.Month,
        value: [today, today],
      },
      {
        label: 'GENERAL.BIZ_LEVEL.INSTITUTION',
        labelI18n: 'GENERAL.BIZ_LEVEL.INSTITUTION',
        index: 'insCode',
        component: this.tplAcquirer,
        customFunc: () => this.selectedAcquirer && this.selectedAcquirer.code,
      },
      {
        label: 'GENERAL.BIZ_LEVEL.AGENT',
        labelI18n: 'GENERAL.BIZ_LEVEL.AGENT',
        index: 'agentCode',
        component: this.tplGroup,
        customFunc: () => this.selectedGroup && this.selectedGroup.code,
      },
      {
        label: 'GENERAL.BIZ_LEVEL.MERCHANT',
        labelI18n: 'GENERAL.BIZ_LEVEL.MERCHANT',
        index: 'intMerCode',
        component: this.tplMerchant,
        customFunc: () => this.selectedMerchant && this.selectedMerchant.code,
      },
      {
        label: 'GENERAL.BIZ_LEVEL.STORE',
        labelI18n: 'GENERAL.BIZ_LEVEL.STORE',
        index: 'intStoreCode',
        component: this.tplStore,
        customFunc: () => this.selectedStore && this.selectedStore.code,
      },
      {
        label: 'GENERAL.INFO.CHANNEL',
        labelI18n: 'GENERAL.INFO.CHANNEL',
        index: 'channel',
        component: this.tplChannel,
        customFunc: () => this.selectedChannel,
      },
      {
        label: 'GENERAL.INFO.TRANSACTION_CURRENCY',
        labelI18n: 'GENERAL.INFO.TRANSACTION_CURRENCY',
        index: 'currency',
        component: this.tplCurrency,
        customFunc: () => this.selectedCurrency && this.selectedCurrency.code,
      },
      {
        label: 'TRADE.STATS.AGGREGATE_LEVEL',
        labelI18n: 'TRADE.STATS.AGGREGATE_LEVEL',
        index: 'level',
        component: this.tplLevel,
        customFunc: () => this.selectedLevel,
      },
    ]
  }

  renderList(res: ITradeStatisticPagination): void {
    const { data: resData, total } = res
    this.data = resData.data
    this.total = total
    this.loading = false
    this.totalData = resData
  }

  queryTableDataWithParams(): void {
    this.loading = true
    this.tradeService.getTradeStatistics(this.params).subscribe(
      res => {
        this.renderList(res)
        this.handleLevelChange(this.selectedLevel)
      },
      error => {
        this.getListError(error)
      },
    )
  }

  download(): void {
    this.tradeService.getTradeStatisticsReport(this.params).subscribe(data => {
      const { url } = data
      openDownloadDialog(url, '下载报表')
    })
  }

  private getCodeTitle(): string {
    switch (this.selectedLevel) {
      case LevelEnum.Institution:
        return this.trans('GENERAL.INSTITUTION.CODE')
      case LevelEnum.Agent:
        return this.trans('GENERAL.AGENT.CODE')
      case LevelEnum.Merchant:
        return this.trans('GENERAL.MERCHANT.NUM')
      case LevelEnum.Store:
        return this.trans('GENERAL.STORE.NUM')
    }
  }

  private getNameTitle(): string {
    switch (this.selectedLevel) {
      case LevelEnum.Institution:
        return this.trans('GENERAL.INSTITUTION.NAME')
      case LevelEnum.Agent:
        return this.trans('GENERAL.AGENT.NAME')
      case LevelEnum.Merchant:
        return this.trans('GENERAL.MERCHANT.NAME')
      case LevelEnum.Store:
        return this.trans('GENERAL.STORE.NAME')
    }
  }
}
